package edu.calvin.djs32.cs214.interpreters.prettyprinter;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

import edu.calvin.cs214.hobbes2008.IntegerTIR;
import edu.calvin.cs214.hobbes2008.StringTIR;
import edu.calvin.cs214.hobbes2008.TupleTIR;

public class PrettyPrinterTest {
	private PrettyPrinter myPrettyPrinter;
	
	@Before
	public void setUp() {
		myPrettyPrinter = new PrettyPrinter();
	}
	
	@Test
	public void shouldPrettyPrintIntegers() {
	  assertEquals("<span class=\"integer\">123</span>", myPrettyPrinter.visitInteger(new IntegerTIR(123)));
	  assertEquals("<span class=\"integer\">253</span>", myPrettyPrinter.visitInteger(new IntegerTIR(253)));
	  assertEquals("<span class=\"integer\">83452</span>", myPrettyPrinter.visitInteger(new IntegerTIR(83452)));
	  assertEquals("<span class=\"integer\">123</span>", myPrettyPrinter.visitInteger(new IntegerTIR(123)));
	}
	
	@Test
	public void shouldPrettyPrintNegativeIntegers() {
	  assertEquals("<span class=\"integer negative\">-123</span>", myPrettyPrinter.visitInteger(new IntegerTIR(-123)));
	  assertEquals("<span class=\"integer negative\">-83452</span>", myPrettyPrinter.visitInteger(new IntegerTIR(-83452)));
	  assertEquals("<span class=\"integer negative\">-9999999</span>", myPrettyPrinter.visitInteger(new IntegerTIR(-9999999)));
	  assertEquals("<span class=\"integer negative\">-123456</span>", myPrettyPrinter.visitInteger(new IntegerTIR(-123456)));
	}
	
	@Test
	public void shouldPrettyPrintStrings() {
	  assertEquals("<span class=\"string\">&lsquo;foo&rsquo;</span>", myPrettyPrinter.visitString(new StringTIR("foo")));
	  assertEquals("<span class=\"string\">&lsquo;foo bar&rsquo;</span>", myPrettyPrinter.visitString(new StringTIR("foo bar")));
	  assertEquals("<span class=\"string\">&lsquo; &rsquo;</span>", myPrettyPrinter.visitString(new StringTIR(" ")));
	}
	
	@Test
	public void shouldAddPreTags(){
		assertEquals("<pre><span class=\"integer\">123</span></pre>", myPrettyPrinter.interpret(new IntegerTIR(123)));
		assertEquals("<pre><span class=\"integer\">123456</span></pre>", myPrettyPrinter.interpret(new IntegerTIR(123456)));
		assertEquals("should pretty print a multiple tuple with pre tags", 
				"<pre><span class=\"tuple\">(<span class=\"integer\">1</span>, " +
				"<span class=\"integer\">2</span>, " +
				"<span class=\"integer\">3</span>)</span></pre>",
				myPrettyPrinter.interpret(new TupleTIR(new IntegerTIR(1), new IntegerTIR(2), new IntegerTIR(3))));
	}
	
	@Test
	public void shouldPrettyPrintTuples() {
	  assertEquals("should pretty print an empty tuple",
	      "<span class=\"tuple\">()</span>", myPrettyPrinter
	          .visitTuple(new TupleTIR()));
	  assertEquals(
			    "should pretty print a singleton tuple",
			    "<span class=\"tuple\">(<span class=\"integer\">1</span>)</span>",
			    myPrettyPrinter.visitTuple(new TupleTIR(new IntegerTIR(1))));
	  assertEquals(
			    "should pretty print a multiple tuple",
			    "<span class=\"tuple\">(<span class=\"integer\">1</span>, " +
			    "<span class=\"integer\">2</span>, " +
			    "<span class=\"integer\">3</span>)</span>",
			    myPrettyPrinter.visitTuple(new TupleTIR(new IntegerTIR(1), new IntegerTIR(2), new IntegerTIR(3))));
	}
	
	@Test
	public void shouldRecognizeTuplesWithDifferentDataTypes(){
		assertEquals("should recognize tuple of strings", 
				"<span class=\"tuple\">(" +
				"<span class=\"string\">&lsquo;a&rsquo;</span>, "+
				"<span class=\"string\">&lsquo;b&rsquo;</span>, "+
				"<span class=\"string\">&lsquo;c&rsquo;</span>)</span>",
			    myPrettyPrinter.visitTuple(new TupleTIR(new StringTIR("a"),new StringTIR("b"),new StringTIR("c"))));
		assertEquals("should recognize a tuple of a tuple", 
				"<span class=\"tuple\">(" +
				"<span class=\"integer\">1</span>, " +
				"<span class=\"tuple\">(" +
				"<span class=\"integer\">2</span>, " +
				"<span class=\"integer\">3</span>" +
				")</span>)</span>",
				myPrettyPrinter.visitTuple(new TupleTIR(new IntegerTIR(1), new TupleTIR(new IntegerTIR(2), new IntegerTIR(3)))));
		assertEquals("should recognize a tuple of mixed types",
				"<span class=\"tuple\">(" +
				"<span class=\"string\">&lsquo;a&rsquo;</span>, "+
				"<span class=\"integer\">5</span>, "+
				"<span class=\"integer\">19</span>)</span>",
			    myPrettyPrinter.visitTuple(new TupleTIR(new StringTIR("a"),new IntegerTIR(5),new IntegerTIR(19))));
	}


}
